package com.fates.common.lang;

import java.io.UnsupportedEncodingException;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang3.StringEscapeUtils;

/**
 * 字符串工具类, 继承org.apache.commons.lang3.StringUtils类
 * 
 * @author fxh
 * @version
 */
public class StringUtils extends org.apache.commons.lang3.StringUtils {

	private static final String CHARSET_NAME = "UTF-8";
	private static Pattern linePattern = Pattern.compile("_(\\w)");
	private static Pattern humpPattern = Pattern.compile("[A-Z]");

	
	/**
	 * 转换为字节数组
	 * 
	 * @param str
	 * @return
	 */
	public static byte[] getBytes(String str) {
		if (str != null) {
			try {
				return str.getBytes(CHARSET_NAME);
			} catch (UnsupportedEncodingException e) {
				return null;
			}
		} else {
			return null;
		}
	}

	/**
	 * 转换为字节数组
	 * 
	 * @param str
	 * @return
	 */
	public static String toString(byte[] bytes) {
		try {
			return new String(bytes, CHARSET_NAME);
		} catch (UnsupportedEncodingException e) {
			return EMPTY;
		}
	}

	/**
	 * 是否包含字符串
	 * 
	 * @param str
	 *            验证字符串
	 * @param strs
	 *            字符串组
	 * @return 包含返回true
	 */
	public static boolean inString(String str, String... strs) {
		if (str != null && strs != null) {
			for (String s : strs) {
				if (str.equals(trim(s))) {
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * 是否包含字符串
	 * 
	 * @param str
	 *            验证字符串
	 * @param strs
	 *            字符串组
	 * @return 包含返回true
	 */
	public static boolean inStringIgnoreCase(String str, String... strs) {
		if (str != null && strs != null) {
			for (String s : strs) {
				if (str.equalsIgnoreCase(trim(s))) {
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * 缩略字符串（不区分中英文字符）
	 * 
	 * @param str
	 *            目标字符串
	 * @param length
	 *            截取长度
	 * @return
	 */
	public static String abbr(String str, int length) {
		if (str == null) {
			return "";
		}
		try {
			StringBuilder sb = new StringBuilder();
			int currentLength = 0;
			for (char c : stripHtml(StringEscapeUtils.unescapeHtml4(str)).toCharArray()) {
				currentLength += String.valueOf(c).getBytes("GBK").length;
				if (currentLength <= length - 3) {
					sb.append(c);
				} else {
					sb.append("...");
					break;
				}
			}
			return sb.toString();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return "";
	}

	/**
	 * <p>
	 * 下划线转驼峰命名：第一个单词首字母小写，其他单词首字母都大写.
	 * </p>
	 * 
	 * <pre>
	 * camelCase("hello_world") == "helloWorld"
	 * </pre>
	 * 
	 * @param lineStr
	 *            转换的字符串, 可能是null值
	 * @return <code>helloWorld</code> 如果字符串单词间带下划线
	 * @since 1.0
	 */
	public static String camelCase(String lineStr) {
		if (null == lineStr || "".equals(lineStr)) {
            return lineStr;
        }
        lineStr = lineStr.toLowerCase();
        Matcher matcher = linePattern.matcher(lineStr);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, matcher.group(1).toUpperCase());
        }
        matcher.appendTail(sb);

        lineStr = sb.toString();

        return lineStr;
	}
	
	/**
	 * <p>
	 * 下划线转帕斯卡命名：单词首字母全大写.
	 * </p>
	 * 
	 * <pre>
	 * pascalCase("hello_world") == "HelloWorld"
	 * </pre>
	 * 
	 * @param lineStr
	 *            转换的字符串, 可能是null值
	 * @return <code>HelloWorld</code> 如果字符串单词间带下划线
	 * @since 1.0
	 */
	public static String pascalCase(String lineStr) {
		 if (null == lineStr || "".equals(lineStr)) {
	            return lineStr;
	        }
		lineStr = camelCase(lineStr);
		return lineStr.substring(0, 1).toUpperCase() + lineStr.substring(1);
	}
	
	/**
	 * <p>
	 * 驼峰或帕斯卡转下划线命名：全字母小写，单词间用下划线分割.
	 * </p>
	 * 
	 * <pre>
	 * underScoreCase("helloWorld") = "hello_world"
	 * underScoreCase("HelloWorld") = "hello_world"
	 * </pre>
	 * 
	 * @param camelStr
	 *            转换的字符串, 可能是null值
	 * @return <code>hello_world</code> 如果字符串为驼峰命名
	 * @since 1.0
	 */
	public static String underScoreCase(String camelStr) {
		camelStr=camelStr.substring(0, 1).toLowerCase() + camelStr.substring(1);
		Matcher matcher = humpPattern.matcher(camelStr);
		StringBuffer sb = new StringBuffer();
		while (matcher.find()) {
			matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase());
		}
		matcher.appendTail(sb);
		return sb.toString();
	}

	/**
	 * 替换掉HTML标签方法
	 */
	public static String stripHtml(String html) {
		if (isBlank(html)) {
			return "";
		}
		// html.replaceAll("\\&[a-zA-Z]{0,9};", "").replaceAll("<[^>]*>", "");
		String regEx = "<.+?>";
		Pattern p = Pattern.compile(regEx);
		Matcher m = p.matcher(html);
		String s = m.replaceAll("");
		return s;
	}

	/**
	 * 替换为手机识别的HTML，去掉样式及属性，保留回车。
	 * 
	 * @param html
	 * @return
	 */
	public static String toMobileHtml(String html) {
		if (html == null) {
			return "";
		}
		return html.replaceAll("<([a-z]+?)\\s+?.*?>", "<$1>");
	}
	
	/**
	 * 转换为JS获取对象值，生成三目运算返回结果
	 * 
	 * @param objectString
	 *            对象串 例如：row.user.id
	 *            返回：!row?'':!row.user?'':!row.user.id?'':row.user.id
	 */
	public static String jsGetVal(String objectString) {
		StringBuilder result = new StringBuilder();
		StringBuilder val = new StringBuilder();
		String[] vals = split(objectString, ".");
		for (int i = 0; i < vals.length; i++) {
			val.append("." + vals[i]);
			result.append("!" + (val.substring(1)) + "?'':");
		}
		result.append(val.substring(1));
		return result.toString();
	}

	/**
	 * 获取随机字符串
	 * 
	 * @param count
	 *            字符串长度
	 * @return
	 */
	public static String getRandomStr(int count) {
		char[] codeSeq = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
				'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
				'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
				'8', '9' };
		Random random = new Random();
		StringBuilder s = new StringBuilder();
		for (int i = 0; i < count; i++) {
			String r = String.valueOf(codeSeq[random.nextInt(codeSeq.length)]);
			s.append(r);
		}
		return s.toString();
	}

	/**
	 * 获取随机字符串
	 * 
	 * @param count
	 *            字符串长度
	 * @return
	 */
	public static String getRandomUpperStr(int count) {
		char[] codeSeq = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
				'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
		Random random = new Random();
		StringBuilder s = new StringBuilder();
		for (int i = 0; i < count; i++) {
			String r = String.valueOf(codeSeq[random.nextInt(codeSeq.length)]);
			s.append(r);
		}
		return s.toString();
	}

	/**
	 * 获取随机数字
	 * 
	 * @param count
	 *            数字长度
	 * @return
	 */
	public static String getRandomNum(int count) {
		char[] codeSeq = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
		Random random = new Random();
		StringBuilder s = new StringBuilder();
		for (int i = 0; i < count; i++) {
			String r = String.valueOf(codeSeq[random.nextInt(codeSeq.length)]);
			s.append(r);
		}
		return s.toString();
	}

	/**
	 * 获取树节点名字
	 * 
	 * @param isShowCode
	 *            是否显示编码<br>
	 *            true or 1：显示在左侧：(code)name<br>
	 *            2：显示在右侧：name(code)<br>
	 *            false or null：不显示编码：name
	 * @param code
	 *            编码
	 * @param name
	 *            名称
	 * @return
	 */
	public static String getTreeNodeName(String isShowCode, String code, String name) {
		if ("true".equals(isShowCode) || "1".equals(isShowCode)) {
			return "(" + code + ") " + StringUtils.replace(name, " ", "");
		} else if ("2".equals(isShowCode)) {
			return StringUtils.replace(name, " ", "") + " (" + code + ")";
		} else {
			return StringUtils.replace(name, " ", "");
		}
	}
    
//	/**
//	 * 测试代码
//	 * 
//	 * @param args
//	 */
//	public static void main(String[] args) {
//
//		
//		String lineCamelStr = "hello_World";
//		System.out.println(lineCamelStr);
//		String lineToCamelStr1=camelCase(lineCamelStr);
//		System.out.println(String.format("方法：下划线转驼峰命名camelCase(\"%s\")；结果：%s", lineCamelStr,lineToCamelStr1));
//		String lineToPascalStr1=pascalCase(lineCamelStr);
//		System.out.println(String.format("方法：下划线转帕斯卡命名pascalCase(\"%s\")；结果：%s", lineCamelStr,lineToPascalStr1));
//		
//		String linePascalStr = "Hello_World";
//		System.out.println(linePascalStr);
//		String lineToCamelStr2=camelCase(linePascalStr);
//		System.out.println(String.format("方法：下划线转驼峰命名camelCase(\"%s\")；结果：%s", linePascalStr,lineToCamelStr2));
//		String lineToPascalStr2=pascalCase(linePascalStr);
//		System.out.println(String.format("方法：下划线转帕斯卡命名pascalCase(\"%s\")；结果：%s", linePascalStr,lineToPascalStr2));
//		
//		String camelStr = "helloWorld";
//		System.out.println(camelStr);
//		String lineStr1=underScoreCase(camelStr);
//		System.out.println(String.format("方法：驼峰或帕斯卡转下划线命名underScoreCase(\"%s\")；结果：%s", camelStr,lineStr1));
//		
//		String pascalStr = "HelloWorld";
//		System.out.println(pascalStr);
//		String lineStr21=underScoreCase(pascalStr);
//		System.out.println(String.format("方法：驼峰或帕斯卡转下划线命名underScoreCase(\"%s\")；结果：%s", pascalStr,lineStr21));
//	
//		String randomStr1=getRandomStr(16);
//		System.out.println(String.format("方法：获取随机字符串getRandomStr(\"%s\")；结果：%s", 16,randomStr1));
//		
//		String randomStr2=getRandomUpperStr(16);
//		System.out.println(String.format("方法：获取随机字符串getRandomUpperStr(\"%s\")；结果：%s", 16,randomStr2));
//		
//		String randomStr3=getRandomNum(16);
//		System.out.println(String.format("方法：获取随机数字getRandomNum(\"%s\")；结果：%s", 16,randomStr3));
//		
//		String strInfo="中盟科技有限公司成立于2002年,中国首批“国家级高新技术企业”。拥有信息系统集成及服务壹级资质,电子与智能化工程专业承包壹级资质,安全技术防范系统设计、施工、维修。";
//		System.out.println(strInfo);
//		String abbrInfo=abbr(strInfo,50);
//		System.out.println(String.format("方法：缩略字符串abbr(\"%s\",%s)；结果：%s", strInfo,50,abbrInfo));
//		
//		
//	}
}
